package com.unism.util;

import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.util.Date;

public class ParseDataType {

	/**
	 * @param args
	 *            63 6D 6E 65 74 00 00 00 00 00 00 00 00 00 00 00
	 */
	public static void main(String[] args) {
		byte[] b = { (byte) 0x63, (byte) 0x6D, (byte) 0x6E, (byte) 0x65,
				(byte) 0x74};
		byte[] c = { (byte) 0x00, (byte) 0x00, (byte) 0x75, (byte) 0x30 };
		byte[] d = { (byte) 0x75, (byte) 0x30 };
		byte e = (byte) 0x0A;
		byte[] f = { (byte) 0x00, (byte) 0x00, (byte) 0x80, (byte) 0x40 };
		byte[] g = { (byte) 0x00, (byte) 0xB0, (byte) 0x4C, (byte) 0x46 };
		byte[] h = { (byte) 0xEB, (byte) 0x98, (byte) 0xA5, (byte) 0xC0 };
		byte[] i = { (byte) 0xCA, (byte) 0x6A, (byte) 0x2E, (byte) 0x97 };
		// 0C 05 0A 0B 0B 1E
		byte[] j = { (byte) 0x0D, (byte) 0x0A, (byte) 0x0A, (byte) 0x0B,
				(byte) 0x0B, (byte) 0x1E };
		
		byte[] k = { (byte)0x31,(byte)0x38,(byte)0x36,(byte)0x32,(byte)0x31,(byte)0x32,(byte)0x31,(byte)0x33,(byte)0x30,(byte)0x37,(byte)0x30,(byte)0x30,(byte)0x33,(byte)0x34,(byte)0x34,(byte)0x00,(byte)0x6C,(byte)0x6F,(byte)0x67 };
		
		//88FBAF224A01001791 14 00 01 01 0C 3131352E32382E33322E39380000000000000000 541F 237DFCFC
		byte[] cc = {(byte) 0x14, (byte) 0x00, (byte) 0x01,(byte) 0x01,(byte)0x0C,(byte)0x31,(byte)0x31,(byte)0x35,(byte)0x2E,(byte)0x32,(byte)0x38,(byte)0x2E,(byte)0x33,(byte)0x32,(byte)0x2E,(byte)0x39,(byte)0x38,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x54,(byte)0x1F};
		byte[] ff = {(byte)0x44,(byte)0xE4,(byte)0xFD,(byte)0x75,(byte)0x00,(byte)0x36,(byte)0xEE,(byte)0x80,(byte)0x00,(byte)0x05,(byte)0x71,(byte)0x40};
		byte[] dd = { (byte) 0x75, (byte) 0x30 };
		byte ee = (byte) 0x0A;
		byte [] ss = ParseDataType.float2byte(Float.valueOf("555.5726318359375").floatValue());
		for (int l = 0; l < ss.length; l++) {
			System.out.println(ss[l]);
			
		}
		System.out.println("-->");
		System.out.println(parseByteArray2CharString(b));
		String tem = "cmnet";
		byte[] ch = getBytes(tem.toCharArray());
		for (int z = 0; z < ch.length;z ++){
			System.out.print(ch[z] + " ");
		}
		System.out.println();
		System.out.println(parseByteArray2IntBy4Byte(c));
		System.out.println(parseByteArray2IntBy2Byte(d));
		System.out.println(parseByteArray2IntBy1Byte(e));
		
		System.out.println(parseByteArray2FloatBy4Byte(f));
		System.out.println(parseByteArray2FloatBy4Byte(g));
		System.out.println(parseByteArray2FloatBy4Byte(h));
		System.out.println(parseByteArray2IPString(i));
		byte [] ip = ipv4Address2BinaryArray("202.106.46.151");
		for (int z = 0; z < ip.length;z ++){
			System.out.print(ip[z] + " ");
		}
		System.out.println();
		
		System.out.println(parseByteArray2DateString(j));
		System.out.println(parseByteArray2CharString(k));
		
	}
	 /**
     * 4位字节数组转换为整型
     * @param b
 	 * @value from  int
 	 * @return
     */
    public static int bytes2Int4(byte[] bs, int from)throws Exception {
		boolean b = isNotOutOfArrLength(bs.length, (from - 1) + 4); 
		if (b) {
	        int s = 0; 
	        int s0 = bs[from + 0] & 0xff;// 最低位 
	        int s1 = bs[from +1] & 0xff; 
	        int s2 = bs[from +2] & 0xff; 
	        int s3 = bs[from +3] & 0xff; 
	 
	        // s0不变 
	        s1 <<= 8; 
	        s2 <<= 16; 
	        s3 <<= 24; 
	        s = s0 | s1 | s2 | s3  ; 
	        return s; 
		} else {
			throw new Exception("byte2Int时数组越界") ;
        }
    }
    
    /**
     * 2位字节数组转换为整型
     * @param b
 	 * @value from  int
 	 * @return
     */
    public static int bytes2Int2(byte[] bs, int from)throws Exception {
		boolean b = isNotOutOfArrLength(bs.length, (from - 1) + 2); 
		if (b) {
	        int s = 0; 
	        int s0 = bs[from + 0] & 0xff;// 最低位 
	        int s1 = bs[from +1] & 0xff; 
	 
	        // s0不变 
	        s1 <<= 8;
	        s = s0 | s1 ; 
	        return s; 
		} else {
			throw new Exception("byte2Int时数组越界") ;
        }
    }
    
    /**
     * 2位字节数组转换为整型
     * @param b
 	 * @value from  int
 	 * @return
     */
    public static int bytes2Int1(byte[] bs, int from)throws Exception {
		boolean b = isNotOutOfArrLength(bs.length, (from - 1) + 1); 
		if (b) {
	        int s = 0; 
	        int s0 = bs[from + 0] & 0xff;// 最低位 

	        // s0不变 
	        s = s0 ; 
	        return s; 
		} else {
			throw new Exception("byte2Int时数组越界") ;
        }
    }
    /**
	 * 判断数组下标是否越界
	 * 
	 * @value bsLength 数组总长度
	 * @value toSite  数组偏移量
	 * @return
	 */
	private static boolean isNotOutOfArrLength(int bsLength, int toSite) {
		if (bsLength > toSite) {
			return true;
		} else {
			return false;
		}
	}
	/**
	 * 
	 * @param b
	 * @return
	 */
	public static char parseByteArray2Char(byte[] b) {

		return getChar(b, 0);
	}

	/**
	 * @param b
	 * @return
	 */
	public static int parseByteArray2IntBy1Byte(byte b) {

		return (b & 0xFF) << 0;

	}

	/**
	 * @param b
	 * @return
	 */
	public static int parseByteArray2IntBy2Byte(byte[] b) {

		return (b[0] & 0xFF) << 8 | (b[1] & 0xFF) << 0;

	}

	/**
	 * @param b
	 * @return
	 */
	public static int parseByteArray2IntBy4Byte(byte[] b) {

		return byteArray2int(b);
	}
	/**
	 * @param b
	 * @return
	 */
	public static int parseByteArray2IntBy4Byte(byte[] b,int from) {

		return byteAllArray2int(b,from);
	}
	/**
	 * @param b
	 * @return
	 */
	public static long parseByteArray2IntBy8Byte(byte[] b) {

		return CByteUtil.byte2Long(b, 0, 8);
	}

	/**
	 * @param b
	 * @param start
	 * @param length
	 * @return
	 */
	public static long parseByteArray2Numberic(byte[] b, long start, long length) {

		return CByteUtil.toNumberic(b, start, length);

	}

	/**
	 * 
	 * @param b
	 * @return
	 */
	public static float parseByteArray2FloatBy4Byte(byte[] b) {

		return getFloat(b, 0);

	}

	/**
	 * 
	 * @param b
	 * @return
	 */
	public static double parseByteArray2FloatBy8Byte(byte[] b) {

		return getDouble(b, 0);

	}

	public static String parseByteArray2CharString(byte[] b) {

		return getChars(b);
	}

	public static String parseByteArray2IPString(byte[] b) {
		String c = "";
		for (int i = 0; i < b.length; i++) {
			if (i < b.length - 1) {
				c += parseByteArray2IntBy1Byte(b[i]) + ".";
			} else {
				c += parseByteArray2IntBy1Byte(b[i]);
			}
		}
		return c;
	}
	/**
	 * 
	 * @param b
	 * @param from
	 * @return
	 */
	public static String parseByteArray2IPString(byte[] b , int from ) {
		String c = "";
		for (int i = 0; i < b.length; i++) {
			if (i < b.length - 1) {
				c += parseByteArray2IntBy1Byte(b[i]) + ".";
			} else {
				c += parseByteArray2IntBy1Byte(b[i]);
			}
		}
		return c;
	}
	
	/**
	 * 
	 * @param ipAdd
	 * @return
	 */
	public static byte[] ipv4Address2BinaryArray(String ipAdd){
		  byte[] binIP = new byte[4];
		  String[] strs = ipAdd.split("\\.");
		  for(int i=0;i<strs.length;i++){
			  binIP[i] = (byte) Integer.parseInt(strs[i]);
		  }
		  return binIP;
	 }

	public static String parseByteArray2DateString(byte[] b) {

		if (b.length != 6) {
			return "";
		}
		@SuppressWarnings("deprecation")
		Date strDate = new Date(b[0], b[1] - 1, b[2], b[3], b[4], b[5]);
		SimpleDateFormat dateFormat = new SimpleDateFormat("yy-MM-dd HH:mm:ss");
		String dateResult = dateFormat.format(strDate);
		return dateResult;
	}
	
	public static String parseByteArray2DateString_yyyy_MM_dd_HH_mm_ss(byte[] b) {

		if (b.length != 6) {
			return "";
		}
		@SuppressWarnings("deprecation")
		Date strDate = new Date(b[0], b[1] - 1, b[2], b[3], b[4], b[5]);
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String dateResult = dateFormat.format(strDate);
		return dateResult;
	}

	/**
	 * 将4字节的byte数组转成int值
	 * 
	 * @param b
	 * @return
	 */
	public static int byteArray2int(byte[] b) {
		byte[] a = new byte[4];
		int i = a.length - 1, j = b.length - 1;
		for (; i >= 0; i--, j--) {// 从b的尾部(即int值的低位)开始copy数据
			if (j >= 0)
				a[i] = b[j];
			else
				a[i] = 0;// 如果b.length不足4,则将高位补0
		}
		int v0 = (a[0] & 0xff) << 24;// &0xff将byte值无差异转成int,避免Java自动类型提升后,会保留高位的符号位
		int v1 = (a[1] & 0xff) << 16;
		int v2 = (a[2] & 0xff) << 8;
		int v3 = (a[3] & 0xff);
		return v0 + v1 + v2 + v3;
	}
	
	/**
	 * 将4字节的byte数组转成int值
	 * 
	 * @param b
	 * @return
	 */
	public static int byteAllArray2int(byte[] b,int from ) {
		byte[] a = new byte[4];
		int i = a.length - 1, j = b.length - from - 1;
		for (; i >= 0; i--, j--) {// 从b的尾部(即int值的低位)开始copy数据
			if (j >= 0)
				a[i] = b[from + j];
			else
				a[i] = 0;// 如果b.length不足4,则将高位补0
		}
		int v0 = (a[0] & 0xff) << 24;// &0xff将byte值无差异转成int,避免Java自动类型提升后,会保留高位的符号位
		int v1 = (a[1] & 0xff) << 16;
		int v2 = (a[2] & 0xff) << 8;
		int v3 = (a[3] & 0xff);
		return v0 + v1 + v2 + v3;
	}

	/**
	 * 将32位的int值转成4字节的byte数组
	 * 
	 * @param num
	 * @return
	 */
	public static byte[] int2byteArray(int num) {
		byte[] result = new byte[4];
		result[0] = (byte) (num >>> 24);// 取最高8位放到0下标
		result[1] = (byte) (num >>> 16);// 取次高8为放到1下标
		result[2] = (byte) (num >>> 8); // 取次低8位放到2下标
		result[3] = (byte) (num); // 取最低8位放到3下标
		return result;
	}

	/**
	 * short 2 字节 byte 1字节
	 * 
	 * 转换short为byte
	 * 
	 * @param b
	 * @param s
	 *            需要转换的short
	 * @param index
	 */
	public static void putShort(byte b[], short s, int index) {
		b[index + 1] = (byte) (s >> 8);
		b[index + 0] = (byte) (s >> 0);
	}

	/**
	 * 通过byte数组取到short
	 * 
	 * @param b
	 * @param index
	 *            第几位开始取
	 * @return
	 */
	public static short getShort(byte[] b, int index) {
		return (short) (((b[index + 1] << 8) | b[index + 0] & 0xff));
	}

	/**
	 * 字符到字节转换
	 * 
	 * @param ch
	 * @return
	 */
	public static void putChar(byte[] bb, char ch, int index) {
		int temp = (int) ch;
		// byte[] b = new byte[2];
		for (int i = 0; i < 2; i++) {
			// 将最高位保存在最低位
			bb[index + i] = new Integer(temp & 0xff).byteValue();
			temp = temp >> 8; // 向右移8位
		}
	}

	/**
	 * 字节到字符转换
	 * 
	 * @param b
	 * @return
	 */
	public static char getChar(byte[] b, int index) {
		int s = 0;
		if (b[index + 1] > 0)
			s += b[index + 1];
		else
			s += 256 + b[index + 0];
		s *= 256;
		if (b[index + 0] > 0)
			s += b[index + 1];
		else
			s += 256 + b[index + 0];
		char ch = (char) s;
		return ch;
	}
	
	

	/**
	 * float转换byte
	 * 
	 * @param bb
	 * @param x
	 * @param index
	 */
	public static void putFloat(byte[] bb, float x, int index) {
		// byte[] b = new byte[4];
		int l = Float.floatToIntBits(x);
		for (int i = 0; i < 4; i++) {
			bb[index + i] = new Integer(l).byteValue();
			l = l >> 8;
		}
	}

	/**
	 * 通过byte数组取得float
	 * 
	 * @param bb
	 * @param index
	 * @return
	 */
	public static float getFloat(byte[] b, int index) {
		int l;
		l = b[index + 0];
		l &= 0xff;
		l |= ((long) b[index + 1] << 8);
		l &= 0xffff;
		l |= ((long) b[index + 2] << 16);
		l &= 0xffffff;
		l |= ((long) b[index + 3] << 24);
		return Float.intBitsToFloat(l);
	}

	/**
	 * double转换byte
	 * 
	 * @param bb
	 * @param x
	 * @param index
	 */
	public static void putDouble(byte[] bb, double x, int index) {
		// byte[] b = new byte[8];
		long l = Double.doubleToLongBits(x);
		for (int i = 0; i < 4; i++) {
			bb[index + i] = new Long(l).byteValue();
			l = l >> 8;
		}
	}

	/**
	 * 通过byte数组取得float
	 * 
	 * @param bb
	 * @param index
	 * @return
	 */
	public static double getDouble(byte[] b, int index) {
		long l;
		l = b[0];
		l &= 0xff;
		l |= ((long) b[1] << 8);
		l &= 0xffff;
		l |= ((long) b[2] << 16);
		l &= 0xffffff;
		l |= ((long) b[3] << 24);
		l &= 0xffffffffl;
		l |= ((long) b[4] << 32);
		l &= 0xffffffffffl;
		l |= ((long) b[5] << 40);
		l &= 0xffffffffffffl;
		l |= ((long) b[6] << 48);
		l &= 0xffffffffffffffl;
		l |= ((long) b[7] << 56);
		return Double.longBitsToDouble(l);
	}

	/**
	 * char转byte
	 * 
	 * @param chars
	 * @return
	 */

	public static byte[] getBytes(char[] chars) {
		Charset cs = Charset.forName("UTF-8");
		CharBuffer cb = CharBuffer.allocate(chars.length);
		cb.put(chars);
		cb.flip();
		ByteBuffer bb = cs.encode(cb);
		return bb.array();
	}

	/**
	 * byte转char
	 * 
	 * @param bytes
	 * @return
	 */

	public static String getChars(byte[] bytes) {
		Charset cs = Charset.forName("UTF-8");
		ByteBuffer bb = ByteBuffer.allocate(bytes.length);
		bb.put(bytes);
		bb.flip();
		CharBuffer cb = cs.decode(bb);
		return cb.toString();// .array();
	}
	
	public static char[] getCharactors (byte[] bytes) {
	      Charset cs = Charset.forName ("UTF-8");
	      ByteBuffer bb = ByteBuffer.allocate (bytes.length);
	      bb.put (bytes);
	                 bb.flip ();
	       CharBuffer cb = cs.decode (bb);
	  
	   return cb.array();
	}

	/**
	 * float2byte(Float.valueOf((float) 555.5726318359375));
	 * 浮点转换为字节
	 * 
	 * @param f
	 * @return
	 */
	public static byte[] float2byte(float f) {

		// 把float转换为byte[]
		int fbit = Float.floatToIntBits(f);

		byte[] b = new byte[4];
		for (int i = 0; i < 4; i++) {
			b[i] = (byte) (fbit >> (24 - i * 8));
		}

		// 翻转数组
		int len = b.length;
		// 建立一个与源数组元素类型相同的数组
		byte[] dest = new byte[len];
		// 为了防止修改源数组，将源数组拷贝一份副本
		System.arraycopy(b, 0, dest, 0, len);
		byte temp;
		// 将顺位第i个与倒数第i个交换
		for (int i = 0; i < len / 2; ++i) {
			temp = dest[i];
			dest[i] = dest[len - i - 1];
			dest[len - i - 1] = temp;
		}

		return dest;

	}
}
